using System;
using System.Threading;
using System.Configuration;

namespace MediaBackup
{
    // BrianSp: This class provides pre-canned entry point for a thread to continually discover and download new media.
    // Note that the TiVo only allows one concurrent download, and worse, if a second one is attempted, it actually 
    // kills the first one.  So... ideal configuration (if you have the luxury of multiple machines) is to have one machine
    // dedicated to discovery and downloading.  If you make that the machine actually hosting the TivoDownloadRootPath you'll
    // find it optimal to also have it doing the decrypting.  I guess you may as well have that guy transcode as well, but 
    // in my configuration this machine is the Home Server and that guy isn't any good at transcoding.  Have as many other
    // machines as you can find doing the transcoding.
    public static class Downloader
    {
        // BrianSp: This wrapper gets all the params from the config file.
        public static void RunFromAppConfig()
        {
            Settings settings = new Settings();
            settings.LoadFromAppSettings();

            string value = ConfigurationManager.AppSettings["Downloader Delay Seconds"];
            int sleepSec = value == null ? 60 : int.Parse(value);

            Run(settings, sleepSec);
        }

        public static void Run(Settings settings, int sleepSec)
        {
            // BrianSp: The ProgressNext method will try to do whatever it has enough settings to do.  Because this method
            // is only intended to do discovery, we null out the settings that enable decrypting and transcoder.
            settings.TivoDecrypter = null;
            settings.Transcoder = null;

            // BrianSp: If that didn't leave us with any work to do, then just return.
            if (settings.TivoIpAddress == null && settings.TivoDecrypter == null && settings.Transcoder == null)
                return;

            // BrianSp: Attempt to preauthenticate all the shares in the settings.
            settings.Authenticate();

            while (true)
            {
                try
                {
                    // BrianSp: The TiVo requires downloads to include a session id (sid) cookie value.  That value
                    // comes from the initial listing query, that's why Discover is called first (and it also just makes
                    // sense of course).  The TivoClient object will remember the value and use it on all subsequent 
                    // requests, so it is important to share this object for both the discovery and the download (which 
                    // happens in ProgressNext).
                    Tivo tivo = new Tivo(settings);
                    tivo.Discover();
                    Item.ProgressNext(settings.TivoDownloadRootPath, tivo, settings);
                }
                catch (Exception e)
                {
                    Log.Write(e);
                }

                // BrianSp: Put in a delay just because the TiVo isn't exactly action packed, so no need to flood it with
                // constant queries.  Also gives a period of time after a download completes where a shutdown can be invoked
                // without cancelling a running download.  A much better solution to safe shutdown is needed however, as it is
                // impossible to accurately predict when a download will complete.
                Thread.Sleep((int)TimeSpan.FromSeconds(sleepSec).TotalMilliseconds);
            }
        }
    }
}
